/**
 * 
 */
package edu.tsinghua.mrpvc.device.aircon;

import java.util.Calendar;
import java.util.Hashtable;
import java.util.Map;

import org.osgi.framework.BundleContext;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.event.EventHandler;
import org.osgi.util.tracker.ServiceTracker;

import edu.tsinghua.mrpvc.device.AirConDevice;


/**
 * @author Tangjian Deng & Wei Feng
 *	Last updated on 2009-11-24 by Tangjian
 */
public class AirConDeviceImpl implements AirConDevice, EventHandler {
	int powerState;
	int windState;
	int temperature;
	int modelState;
	String ID;
	boolean valid;
	//static String topic = "863pvc/Device/ACCtrl/State";
	ServiceTracker tracker;
	
	public AirConDeviceImpl(BundleContext context, String ID){
		powerState = 0;
		windState = 1;
		temperature = 20;
		modelState = 0;
		this.ID = ID;
		valid = true;
		tracker = new ServiceTracker(context, EventAdmin.class.getName(), null);
		tracker.open();
	}

	void generEvent(){
		System.out.println(Calendar.getInstance().getTime().toLocaleString() +
				" Aircondition: state changed and post event");
		EventAdmin eventAdmin = (EventAdmin) tracker.getService();
		if(eventAdmin != null){
			Map<String, String> propers = new Hashtable<String, String>();
			propers.put(AirConDevice.EVENT_PROPER_POWER_STATE, powerState == 0 ? AirConDevice.Constants.POWER_OFF : AirConDevice.Constants.POWER_ON);
			if(Integer.toString(modelState).equals(AirConDevice.Constants.MODE_AUTO)){
				propers.put(AirConDevice.EVENT_PROPER_MODE, AirConDevice.Constants.MODE_AUTO);
			}
			else if(Integer.toString(modelState).equals(AirConDevice.Constants.MODE_COOL)){
				propers.put(AirConDevice.EVENT_PROPER_MODE, AirConDevice.Constants.MODE_COOL);
			}
			else if(Integer.toString(modelState).equals(AirConDevice.Constants.MODE_HEAT)){
				propers.put(AirConDevice.EVENT_PROPER_MODE, AirConDevice.Constants.MODE_HEAT);
			}
			if(Integer.toString(windState).equals(AirConDevice.Constants.WIND_ONE)){
				propers.put(AirConDevice.EVENT_PROPER_WIND, AirConDevice.Constants.WIND_ONE);
			}
			else if(Integer.toString(windState).equals(AirConDevice.Constants.WIND_TWO)){
				propers.put(AirConDevice.EVENT_PROPER_WIND, AirConDevice.Constants.WIND_TWO);
			}			
			else if(Integer.toString(windState).equals(AirConDevice.Constants.WIND_THREE)){
				propers.put(AirConDevice.EVENT_PROPER_WIND, AirConDevice.Constants.WIND_THREE);
			}
			else if(Integer.toString(windState).equals(AirConDevice.Constants.WIND_FOUR)){
				propers.put(AirConDevice.EVENT_PROPER_WIND, AirConDevice.Constants.WIND_FOUR);
			}
			propers.put(AirConDevice.EVENT_PROPER_ID, ID);
			propers.put(AirConDevice.EVENT_PROPER_ISVALID, valid == true ? AirConDevice.Constants.ISVALID_TURE : AirConDevice.Constants.ISVALID_FALSE);
			propers.put(AirConDevice.EVENT_PROPER_TMP, Integer.toString(temperature));
			Event event = new Event(AirConDevice.EVENT_TOPIC_STATE, propers);
			eventAdmin.postEvent(event);			
		}
	}
	@Override
	public int downTemperature() {
		// TODO Auto-generated method stub
		temperature--;
		System.out.print(Calendar.getInstance().getTime().toLocaleString() + " ");
		System.out.println("Airconditon: down temperature executed");
		generEvent();
		return this.temperature;
	}

	@Override
	public int getCurTemperature() {
		// TODO Auto-generated method stub
		
		return this.temperature;
	}

	@Override
	public String getID() {
		// TODO Auto-generated method stub
		return ID;
	}

	@Override
	public int getModeState() {
		// TODO Auto-generated method stub
		return modelState;
	}

	@Override
	public int getPowerState() {
		// TODO Auto-generated method stub
		return powerState;
	}

	@Override
	public int getWindState() {
		// TODO Auto-generated method stub
		return windState;
	}

	@Override
	public boolean isValid() {
		// TODO Auto-generated method stub
		return valid;
	}

	@Override
	public int powerOff() {
		// TODO Auto-generated method stub
		powerState = 0;
		System.out.print(Calendar.getInstance().getTime().toLocaleString() + " ");
		System.out.println("Airconditon: Power Off executed");
		generEvent();
		return 1;
	}

	@Override
	public int powerOn() {
		// TODO Auto-generated method stub
		powerState = 1;
		System.out.print(Calendar.getInstance().getTime().toLocaleString() + " ");
		System.out.println("Airconditon: Power On executed");
		generEvent();
		return 1;
	}

	/*
	public int serTemperatrue(int temperature) {
		// TODO Auto-generated method stub
		this.temperature = temperature;
		generEvent();
		return this.temperature;
	}*/

	@Override
	public int tuneMode() {
		// TODO Auto-generated method stub
		modelState = (modelState + 1) % 3;
		System.out.print(Calendar.getInstance().getTime().toLocaleString() + " ");
		System.out.println("Airconditon: tune mode executed");
		generEvent();
		return modelState;
	}

	@Override
	public int tuneWind() {
		// TODO Auto-generated method stub
		windState = (windState + 1) % 5;
		System.out.print(Calendar.getInstance().getTime().toLocaleString() + " ");
		System.out.println("Airconditon: tune wind executed");
		generEvent();
		return windState;
	}

	@Override
	public int upTemperature() {
		// TODO Auto-generated method stub
		temperature++;
		System.out.print(Calendar.getInstance().getTime().toLocaleString() + " ");
		System.out.println("Airconditon: up temperature executed");
		generEvent();
		return temperature;
	}

	@Override
	public void handleEvent(Event event) {
		// TODO Auto-generated method stub
		if(event.getTopic().equals(AirConDevice.EVENT_TOPIC_ISVALID)){
			if(event.getProperty(AirConDevice.EVENT_PROPER_ID) != null && event.getProperty(AirConDevice.EVENT_PROPER_ID).equals(ID)){
				generEvent();
			}
			else{
				System.out.println("***AirconDevice ID not match***");
			}
		}
		else if(event.getTopic().equals(AirConDevice.EVENT_TOPIC_POWER)){
			if(event.getProperty(AirConDevice.EVENT_PROPER_ID) != null && event.getProperty(AirConDevice.EVENT_PROPER_ID).equals(ID)){
				this.powerState = Integer.parseInt(event.getProperty(AirConDevice.EVENT_PROPER_POWER_STATE).toString());
				generEvent();
			}
			else{
				System.out.println("***AirconDevice ID not match***");
			}			
		}
		else if(event.getTopic().equals(AirConDevice.EVENT_TOPIC_TUNEMODE)){
			if(event.getProperty(AirConDevice.EVENT_PROPER_ID) != null && event.getProperty(AirConDevice.EVENT_PROPER_ID).equals(ID)){
				modelState = (modelState + 1) % 3;
				generEvent();
			}
			else{
				System.out.println("***AirconDevice ID not match***");
			}			
		}
		else if(event.getTopic().equals(AirConDevice.EVENT_TOPIC_TUNEWIND)){
			if(event.getProperty(AirConDevice.EVENT_PROPER_ID) != null && event.getProperty(AirConDevice.EVENT_PROPER_ID).equals(ID)){
				windState = (windState + 1) % 5;
				if(windState == 0){
					windState = 1;
				}
				generEvent();
			}
			else{
				System.out.println("***AirconDevice ID not match***");
			}
			
		}
		else if(event.getTopic().equals(AirConDevice.EVENT_TOPIC_TUNETEMP)){
			if(event.getProperty(AirConDevice.EVENT_PROPER_ID) != null && event.getProperty(AirConDevice.EVENT_PROPER_ID).equals(ID)){
				if(event.getProperty(AirConDevice.EVENT_PROPER_CTRL) != null){
					if(event.getProperty(AirConDevice.EVENT_PROPER_CTRL).equals(Constants.CTRL_TMP_UP)){
						this.temperature++;
					}
					else if(event.getProperty(AirConDevice.EVENT_PROPER_CTRL).equals(Constants.CTRL_TMP_DOWN)){
						this.temperature--;
					}
				}
				generEvent();
			}
			else{
				System.out.println("***AirconDevice ID not match***");
			}
			
		}
		else if(event.getTopic().equals(AirConDevice.EVENT_TOPIC_MODE)){
			if(event.getProperty(AirConDevice.EVENT_PROPER_ID) != null && event.getProperty(AirConDevice.EVENT_PROPER_ID).equals(ID)){
				generEvent();
			}
			else{
				System.out.println("***AirconDevice ID not match***");
			}
		}
		else if(event.getTopic().equals(AirConDevice.EVENT_TOPIC_WIND)){
			if(event.getProperty(AirConDevice.EVENT_PROPER_ID) != null && event.getProperty(AirConDevice.EVENT_PROPER_ID).equals(ID)){
				generEvent();
			}
			else{
				System.out.println("***AirconDevice ID not match***");
			}
		}
		else if(event.getTopic().equals(AirConDevice.EVENT_TOPIC_TEMP)){
			if(event.getProperty(AirConDevice.EVENT_PROPER_ID) != null && event.getProperty(AirConDevice.EVENT_PROPER_ID).equals(ID)){
				generEvent();
			}
			else{
				System.out.println("***AirconDevice ID not match***");
			}
		}		
	}

	/* (non-Javadoc)
	 * @see edu.tsinghua.mrpvc.device.AirConDevice#setTemperature(int)
	 */
	@Override
	public int setTemperature(int tmp) {
		this.temperature = tmp;
		return tmp;
	}
}
